import pygame
from pygame.locals import *
import random
import constant
from constant import *
from ball import *
from result import *
from round import *

class Game :
    def __init__(self, total_balls, max_colors, max_rounds) :
        self.max_rounds = max_rounds
        self.rounds = list()
        self.current_round = None
        self.max_colors = max_colors
        self.total_balls = total_balls
        self.colors = constant.getColors_constants(self.max_colors + 1)
        self.answer = self.__createAnswer__()
        self.answer_images = self.__createAnswerImages__()
        self.background = self.__createBackground__()
        self.background_end = self.__createBackgroundEnd__()
        self.main = None
        self.finished = False
        self.newRound()
        
    def setMain(self, main) :
        self.main = main        
        
    def __createBackgroundEnd__(self) :
        background = {}
        background['lost'] = pygame.image.load('images/background_end_lost.png').convert()
        background['win'] = pygame.image.load('images/background_end_win.png').convert()
        return background        
        
    def __createBackground__(self) :
        background = pygame.image.load('images/background.png').convert()
        return background
        
    def __createAnswer__(self) :
        r = random.Random()
        answer = list()
        
        for i in xrange(self.total_balls) :
            index = r.randint(1,self.max_colors)
            answer.append(self.colors[index])
            
        return answer           
            
    def newRound(self) :
        if (not self.hasWon()) or (not self.hasFinished()) :
            if len(self.rounds) == self.max_rounds :
                self.finished = True
            else :
                for round in self.rounds :
                    if round is self.current_round :
                        round.finish()
                    else:
                        round.downPosition()
                round_id = len(self.rounds) + 1
                round = Round(round_id,self.total_balls)
                self.rounds.append(round)
                self.current_round = round
     
    def previousColor(self, x, y) :
        self.current_round.previousColor(x, y, self.max_colors+1)     
     
    def nextColor(self, x, y) :
        self.current_round.nextColor(x, y, self.max_colors+1)
        
    def process(self) :
        results = list()
        answer_temp = self.answer[:]
        guesses = self.current_round.toList()
        
        for i in xrange(len(guesses)) :
            results.append(Result(INCORRECT, i))
        
        for i in xrange(len(answer_temp)):
            answer = answer_temp[i]
            guess = guesses[i]
            
            if answer == guess:
                results[i].setType(CORRECT)
                answer_temp[i] = None
                guesses[i] = None
                
        
        for i in xrange(len(guesses)):
            guess = guesses[i]
            
            if guess <> None:
                try:
                    index = answer_temp.index(guess)
                    results[i].setType(MISPLACED)
                    answer_temp[index] = None
                    guesses[i] = None
                except:
                    pass
        
        self.current_round.setResult(results)
        
    def paint(self, screen) :
        if self.hasWon() :
            self.__lastWinPaint__(screen)
        elif self.hasLost() :
            self.__lastLostPaint__(screen)
        else:
            screen.blit(self.background, (0,0))
            self.paintNumberOfTries(screen)
            for round in self.rounds :
                round.paint(screen)
        
    
        
    def hasFinished(self) :
        return self.finished
        
    def hasWon(self) :
        if self.current_round <> None:
            if self.current_round.isResultCorrect() :
                self.finished = True
                return True
        return False
        
    def hasLost(self):
        return (self.hasFinished()) and (self.hasWon() == False)
        
    def __lastWinPaint__(self, screen) :
        screen.blit(self.background_end['win'], (0,0))
        self.__answerPaint__(screen)
        
    def __lastLostPaint__(self, screen) :
        screen.blit(self.background_end['lost'], (0,0))
        self.__answerPaint__(screen)
        
    def __answerPaint__(self, screen) :
        for ball in self.answer_images :
            ball.paint(screen)
        
    def __createAnswerImages__(self) :
        images = list()
        for i in xrange(len(self.answer)) :
            images.append(Ball(self.answer[i], BALL_ROBOT, i))
        return images
        
    def paintNumberOfTries(self, screen) :
        DEZENA, UNIDADE = 0, 1
        
        def findNumberScreenPosition(position) :
            x, y = images.NUMBER_START_X, images.NUMBER_START_Y
            x += position * (images.SPRITE_NUMBER_X + images.NUMBER_DIFF)
            return (x, y) 
            
            
        n = self.max_rounds - len(self.rounds) + 1           
        dezenas = n / 10
        unidades = n % 10
        
        spriteD = images.getImageNumber(dezenas)
        spriteU = images.getImageNumber(unidades)
        screen.blit(spriteD, findNumberScreenPosition(DEZENA))
        screen.blit(spriteU, findNumberScreenPosition(UNIDADE))
        
   